import Foundation
import CoreLocation

class GoogleMapsService {
    static let shared = GoogleMapsService()
    
    private var apiKey: String {
        return GeocodingConfig.shared.googleApiKey
    }
    private let baseURL = "https://maps.googleapis.com/maps/api"
    
    private init() {}
    
    // MARK: - 正向地理编码（地址转坐标）
    func geocodeAddress(_ address: String) async -> CLLocationCoordinate2D? {
        let encodedAddress = address.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
        let urlString = "\(baseURL)/geocode/json?address=\(encodedAddress)&key=\(apiKey)"
        
        guard let url = URL(string: urlString) else {
            print("🗺️ [Google] 无效URL: \(urlString)")
            return nil
        }
        
        do {
            let (data, response) = try await URLSession.shared.data(from: url)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                print("🗺️ [Google] 无效HTTP响应")
                return nil
            }
            
            print("🗺️ [Google] 正向地理编码响应状态: \(httpResponse.statusCode)")
            
            if httpResponse.statusCode == 200 {
                let result = try JSONDecoder().decode(GoogleGeocodeResponse.self, from: data)
                
                if result.status == "OK" && !result.results.isEmpty {
                    let location = result.results[0].geometry.location
                    let coordinate = CLLocationCoordinate2D(
                        latitude: location.lat,
                        longitude: location.lng
                    )
                    print("🗺️ [Google] 正向地理编码成功: \(address) -> \(coordinate)")
                    return coordinate
                } else {
                    print("🗺️ [Google] 正向地理编码失败: \(result.status)")
                }
            } else {
                print("🗺️ [Google] HTTP错误: \(httpResponse.statusCode)")
            }
        } catch {
            print("🗺️ [Google] 正向地理编码异常: \(error)")
        }
        
        return nil
    }
    
    // MARK: - 逆向地理编码（坐标转地址）
    func reverseGeocode(coordinate: CLLocationCoordinate2D) async -> GlobalLocationAddressInfo? {
        let urlString = "\(baseURL)/geocode/json?latlng=\(coordinate.latitude),\(coordinate.longitude)&key=\(apiKey)&language=zh-CN"
        
        guard let url = URL(string: urlString) else {
            print("🗺️ [Google] 无效URL: \(urlString)")
            return nil
        }
        
        var request = URLRequest(url: url)
        request.timeoutInterval = 30.0 // 增加超时时间到30秒
        
        do {
            let (data, response) = try await URLSession.shared.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                print("🗺️ [Google] 无效HTTP响应")
                return nil
            }
            
            print("🗺️ [Google] 逆向地理编码响应状态: \(httpResponse.statusCode)")
            
            if httpResponse.statusCode == 200 {
                let result = try JSONDecoder().decode(GoogleGeocodeResponse.self, from: data)
                
                if result.status == "OK" && !result.results.isEmpty {
                    let addressComponent = result.results[0].addressComponents
                    let formattedAddress = result.results[0].formattedAddress
                    
                    let addressInfo = GlobalLocationAddressInfo(
                        country: extractComponent(addressComponent, types: ["country"]),
                        province: extractComponent(addressComponent, types: ["administrative_area_level_1"]),
                        city: extractComponent(addressComponent, types: ["locality", "administrative_area_level_2"]),
                        district: extractComponent(addressComponent, types: ["sublocality", "administrative_area_level_3"]),
                        township: nil,
                        street: extractComponent(addressComponent, types: ["route"]),
                        poiName: nil,
                        formattedAddress: formattedAddress
                    )
                    
                    print("🗺️ [Google] 逆向地理编码成功: \(coordinate) -> \(formattedAddress)")
                    return addressInfo
                } else {
                    print("🗺️ [Google] 逆向地理编码失败: \(result.status)")
                }
            } else {
                print("🗺️ [Google] HTTP错误: \(httpResponse.statusCode)")
            }
        } catch {
            print("🗺️ [Google] 逆向地理编码异常: \(error)")
        }
        
        return nil
    }
    
    // MARK: - 辅助方法
    private func extractComponent(_ components: [GoogleAddressComponent], types: [String]) -> String {
        for component in components {
            for type in types {
                if component.types.contains(type) {
                    return component.longName
                }
            }
        }
        return ""
    }
    
    // MARK: - 异步扩展方法
    func fetchAddressInfoAsync(coordinate: CLLocationCoordinate2D) async -> GlobalLocationAddressInfo? {
        return await reverseGeocode(coordinate: coordinate)
    }
}

// MARK: - Google Maps API 响应模型
struct GoogleGeocodeResponse: Codable {
    let status: String
    let results: [GeocodeResult]
}

struct GeocodeResult: Codable {
    let formattedAddress: String
    let addressComponents: [GoogleAddressComponent]
    let geometry: Geometry
    
    enum CodingKeys: String, CodingKey {
        case formattedAddress = "formatted_address"
        case addressComponents = "address_components"
        case geometry
    }
}

struct GoogleAddressComponent: Codable {
    let longName: String
    let shortName: String
    let types: [String]
    
    enum CodingKeys: String, CodingKey {
        case longName = "long_name"
        case shortName = "short_name"
        case types
    }
}

struct Geometry: Codable {
    let location: Location
}

struct Location: Codable {
    let lat: Double
    let lng: Double
} 